#ifndef _AREA_HPP_20120625
#define _AREA_HPP_20120625

#include "base.hpp"

#include "singleton.hpp"

#include "scence_cmd.hpp"
#include "cmd_comm.hpp"
#include "cmd_type.hpp"

#include "mj2_table.hpp"
#include "table.hpp"
#include "room.hpp"

using namespace cmd;

class Area : public Singleton<Area>
{
	public :
		typedef __gnu_cxx::hash_map<ROOMID, Room*> RoomMap;
		typedef RoomMap::iterator RoomMap_Iter;

		typedef __gnu_cxx::hash_map<uint32_t, Table*> TableMap;
		typedef TableMap::iterator TableMap_Iter;

	public :
		Area();
		~Area();

		template <typename _Table>
		int init(AREAID aid, ROOMNUM room_num, TABLENUM table_num);

		Room * find_room(ROOMID id);
		Table * find_table(ROOMID rid, TABLEID tid);

		int enter_room(Connection & conn, const SSMJ2EnterRoomReq & req);

	private :
		uint32_t table_position(ROOMID rid, TABLEID tid)
		{
			return ((((uint32_t)rid) << 16) | ((uint32_t)tid));
		}

	public :
		AREAID     _id;

		RoomMap    _room_map;
		TableMap   _table_map;

		DECL_LOGGER(logger);
};

template <typename _Table>
int Area::init(AREAID aid, ROOMNUM room_num, TABLENUM table_num)
{
	_id = aid;

	for (ROOMNUM i = 1; i <= room_num; ++ i)
	{
		Room * pRoom = new Room();

		assert(NULL != pRoom);
		pRoom->init<majiang2::MaJiang2Table>(i, table_num);
		_room_map.insert(std::make_pair(i, pRoom));

		Room::TableMap_Iter iter = pRoom->_table_map.begin();
		for (; iter != pRoom->_table_map.end(); ++ iter)
		{
			Table *    pTable = iter->second;
			uint32_t  tbl_pos = table_position(i, pTable->_id);
			
			assert(_table_map.insert(std::make_pair(tbl_pos, pTable)).second);
		}
	}

	return 0;
}

#endif

